/** @jsxImportSource @emotion/react */
import { jsx, css } from "@emotion/react";
import * as React from "react";
import { mergeRefs } from "react-merge-refs";
import {
  useFloating,
  autoUpdate,
  offset,
  flip,
  shift,
  useHover,
  useFocus,
  useDismiss,
  useRole,
  useInteractions,
  FloatingPortal
} from "@floating-ui/react";
import type { Placement } from "@floating-ui/react";



interface TooltipOptions {
  initialOpen?: boolean;
  placement?: Placement;
  open?: boolean;
  onOpenChange?: (open: boolean) => void;
}

export function useTooltip({
                             initialOpen = false,
                             placement = "top",
                             open: controlledOpen,
                             onOpenChange: setControlledOpen
                           }: TooltipOptions = {}) {
  const [uncontrolledOpen, setUncontrolledOpen] = React.useState(initialOpen);

  const open = controlledOpen ?? uncontrolledOpen;
  const setOpen = setControlledOpen ?? setUncontrolledOpen;

  const data = useFloating({
    placement,
    open,
    onOpenChange: setOpen,
    whileElementsMounted: autoUpdate,
    middleware: [offset(5), flip(), shift()]
  });

  const context = data.context;

  const hover = useHover(context, {
    move: false,
    enabled: controlledOpen == null
  });
  const focus = useFocus(context, {
    enabled: controlledOpen == null
  });
  const dismiss = useDismiss(context);
  const role = useRole(context, { role: "tooltip" });

  const interactions = useInteractions([hover, focus, dismiss, role]);

  return React.useMemo(
      () => ({
        open,
        setOpen,
        ...interactions,
        ...data
      }),
      [open, setOpen, interactions, data]
  );
}

type ContextType = ReturnType<typeof useTooltip> | null;

const TooltipContext = React.createContext<ContextType>(null);

export const useTooltipState = () => {
  const context = React.useContext(TooltipContext);

  if (context == null) {
    throw new Error("Tooltip components must be wrapped in <Tooltip />");
  }

  return context;
};

//没有箭头了
export function Tooltip({
                          children,
                          ...options
                        }: { children: React.ReactNode } & TooltipOptions) {
  // This can accept any props as options, e.g. `placement`,
  // or other positioning options.
  const tooltip = useTooltip(options);
  return (
      <TooltipContext.Provider value={tooltip}>
        {children}
      </TooltipContext.Provider>
  );
}

export const TooltipTrigger =
    ({ children, asChild = false,ref, ...props } :React.HTMLProps<HTMLElement> & { asChild?: boolean } )=> {
  const state = useTooltipState();

  const childrenRef = (children as any).ref;
  const refnew = React.useMemo(
      () => mergeRefs([state.refs.setReference, ref, childrenRef]),
      [state.refs.setReference, ref, childrenRef]
  );

  // `asChild` allows the user to pass any element as the anchor
  if (asChild && React.isValidElement(children)) {
    return React.cloneElement(
        children,
        state.getReferenceProps({
          ref: refnew,
          ...props,
          ...(children.props as any),
          "data-state": state.open ? "open" : "closed"
        })
    );
  }

  return (
      <button
          ref={refnew}
          // The user can style the trigger based on the state
          data-state={state.open ? "open" : "closed"}
          {...state.getReferenceProps(props)}
      >
        {children}
      </button>
  );
};

export const TooltipContent =
    ({ref, ...props}:React.HTMLProps<HTMLDivElement> )=> {
  const state = useTooltipState();

  const refnew = React.useMemo(() => mergeRefs([state.refs.setFloating, ref]), [
    state.refs.setFloating,
    ref
  ]);

  return (
      <FloatingPortal>
        {state.open && (
            <div
                ref={refnew}
                style={{
                  position: state.strategy,
                  top: state.y ?? 0,
                  left: state.x ?? 0,
                  visibility: state.x == null ? "hidden" : "visible",
                  width: 'max-content',
                  backgroundColor: '#444',
                  color: 'white',
                  fontSize: '90%',
                  padding: '4px 8px',
                  borderRadius: '4px',

                  ...props.style
                }}
                {...state.getFloatingProps(props)}
            />
        )}
      </FloatingPortal>
  );
};


/*例子  https://codesandbox.io/s/xenodochial-grass-js3bo9?file=/src/App.tsx:227-383
      <Tooltip>
        <TooltipTrigger>My trigger</TooltipTrigger>
        <TooltipContent>My tooltip</TooltipContent>
      </Tooltip>
* */
